/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.nanosl.norg.general.gui;

import com.nanosl.lib.db.Manager;
import com.nanosl.norg.ent.Code;
import com.nanosl.norg.ent.Employee;
import com.nanosl.norg.ent.Person;
import com.nanosl.norg.util.NTopComponent;
import java.awt.Color;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.swing.JOptionPane;
import org.netbeans.api.settings.ConvertAsProperties;
import org.netbeans.spi.actions.AbstractSavable;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.NotifyDescriptor.Confirmation;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.UndoRedo;
import org.openide.util.Exceptions;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(
    dtd = "-//com.nanosl.credit.editor//EmployeeEditor//EN",
autostore = false)
@TopComponent.Description(
    preferredID = "EmployeeEditorTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE", 
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "editor", openAtStartup = false)
@ActionID(category = "Window", id = "com.nanosl.credit.editor.EmployeeEditorTopComponent")
@ActionReference(path = "Menu/Editor", position = 6)
@TopComponent.OpenActionRegistration(
    displayName = "#CTL_EmployeeEditorAction",
preferredID = "EmployeeEditorTopComponent")
@Messages({
    "CTL_EmployeeEditorAction=EmployeeEditor",
    "CTL_EmployeeEditorTopComponent=EmployeeEditor Window",
    "HINT_EmployeeEditorTopComponent=This is a EmployeeEditor window"
})
public final class EmployeeEditorTopComponent extends NTopComponent implements LookupListener {

    public static void display() {
        EmployeeEditorTopComponent tc = (EmployeeEditorTopComponent) WindowManager.getDefault().findTopComponent("EmployeeEditorTopComponent");
        tc.open();
        tc.requestActive();
        tc.requestFocus();
    }
    public EmployeeEditorTopComponent() {
        initComponents();
        setName(Bundle.CTL_EmployeeEditorTopComponent());
        setToolTipText(Bundle.HINT_EmployeeEditorTopComponent());
        instanceContent = new InstanceContent();
        associateLookup(new AbstractLookup(instanceContent));
        codeTextField.getDocument().addUndoableEditListener(UndoRedoManager);
        nicTextField.getDocument().addUndoableEditListener(UndoRedoManager);
        firstNameTextField.getDocument().addUndoableEditListener(UndoRedoManager);
        lastNameTextField.getDocument().addUndoableEditListener(UndoRedoManager);
        codeTextField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                modify();
            }
        });
        nicTextField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                modify();
            }
        });
        firstNameTextField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                modify();
            }
        });
        lastNameTextField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                modify();
            }
        });
    }

    private void modify() {
        if (getLookup().lookup(EmployeeSavable.class) == null) {
            instanceContent.add(new EmployeeSavable());
        }
    }

    @Override
    public void componentOpened() {
        result = WindowManager.getDefault().findTopComponent("EntityExplorerTopComponent").getLookup().lookupResult(Employee.class);
        result.addLookupListener(this);
        resultChanged(new LookupEvent(result));

    }

    @Override
    public void componentClosed() {
        result.removeLookupListener(this);
        result = null;
    }

    @Override
    public void resultChanged(LookupEvent lookupEvent) {
        Lookup.Result r = (Lookup.Result) lookupEvent.getSource();
        Collection<Employee> coll = r.allInstances();

        if (!coll.isEmpty()) {
            EmployeeEditorTopComponent tc = (EmployeeEditorTopComponent) WindowManager.getDefault().findTopComponent("EmployeeEditorTopComponent");
            tc.resetFields();
            tc.open();
            tc.requestVisible();
//            tc.requestActive();
            for (Employee employee : coll) {
                Person person = employee.getPerson();

                codeTextField.setText(employee.getEmployeePK().getId() + "");
                nicTextField.setText(person.getNic());
                firstNameTextField.setText(person.getFirstName());
                lastNameTextField.setText(person.getLastName());
            }
        } else {
            codeTextField.setText("");
            nicTextField.setText("");
            firstNameTextField.setText("");
            lastNameTextField.setText("");
        }
    }

    public void resetFields() {
        codeTextField.setText("");
        nicTextField.setText("");
        firstNameTextField.setText("");
        lastNameTextField.setText("");
        codeTextField.requestFocus();
    }

    @Override
    public UndoRedo getUndoRedo() {
        return UndoRedoManager;
    }

    private void fillData(String nic) {
        Person person = manager.find(Person.class, nic);
        if (person != null) {
            firstNameTextField.setText(person.getFirstName());
            lastNameTextField.setText(person.getLastName());
            Collection<Employee> employees = person.getEmployeeCollection();
            for (Iterator<Employee> it = employees.iterator(); it.hasNext();) {
                Employee employee = it.next();
                codeTextField.setText(employee.getEmployeePK().getId() + "");
            }
        }
    }

    private class EmployeeSavable extends AbstractSavable {

        String codeString, nic, firstName, lastName;

        EmployeeSavable() {
            register();
        }

        @Override
        protected String findDisplayName() {
            nic = nicTextField.getText();
            firstName = firstNameTextField.getText();
            lastName = lastNameTextField.getText();
            return "( " + codeString + " ) " + nic + " " + firstName;
        }

        @Override
        protected void handleSave() throws IOException {
            codeString = codeTextField.getText().trim();
            nic = nicTextField.getText();
            firstName = firstNameTextField.getText();
            lastName = lastNameTextField.getText();
            if (!isText(firstName) | !isText(lastName) | !isNIC(nic)) {
                showError("Incomplete Data");
                return;
            }
            Confirmation message = new Confirmation(
                    "Do you want to save \n ( " + firstName + " ) " + nic + "?", NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.QUESTION_MESSAGE);
            Object result = DialogDisplayer.getDefault().notify(message);
            if (NotifyDescriptor.YES_OPTION.equals(result)) {
                Code code = manager.find(Code.class, "EMPLOYEE");
                if (code == null) {
                    code = new Code("EMPLOYEE");
                    code.setCodeInt(1);
                }
                List<Serializable> serializables = new ArrayList<Serializable>();
                Person person = manager.find(Person.class, nic);
                Employee employee = null;
                if (person != null) {
                    Collection<Employee> employees = person.getEmployeeCollection();
                    for (Iterator<Employee> it = employees.iterator(); it.hasNext();) {
                        employee = it.next();
                        break;
                    }
                } else {
                    person = new Person(nic);
                }
                if (employee == null) {
                    employee = new Employee();//code.getCodeInt()
                    code.setCodeInt(code.getCodeInt() + 1);
                    serializables.add(code);
                }
                person.setFirstName(firstName);
                person.setLastName(lastName);
                employee.setPerson(person);

                serializables.add(person);
                serializables.add(employee);
                manager.update(serializables);
                manager.clearCache();
                resetFields();
                tc().instanceContent.remove(this);
                unregister();

            }
        }

        EmployeeEditorTopComponent tc() {
            return EmployeeEditorTopComponent.this;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof EmployeeSavable) {
                EmployeeSavable m = (EmployeeSavable) obj;
                return tc() == m.tc();
            }
            return false;
        }

        @Override
        public int hashCode() {
            return tc().hashCode();
        }
    }
    private Lookup.Result result = null;
    private UndoRedo.Manager UndoRedoManager = new UndoRedo.Manager();
    private InstanceContent instanceContent;

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        nicTextField = new javax.swing.JTextField();
        firstNameTextField = new javax.swing.JTextField();
        lastNameTextField = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        codeTextField = new javax.swing.JTextField();
        saveButton = new javax.swing.JButton();
        clearButton = new javax.swing.JButton();

        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(EmployeeEditorTopComponent.class, "EmployeeEditorTopComponent.jLabel1.text_1")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(EmployeeEditorTopComponent.class, "EmployeeEditorTopComponent.jLabel2.text_1")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(EmployeeEditorTopComponent.class, "EmployeeEditorTopComponent.jLabel3.text_1")); // NOI18N

        nicTextField.setText(org.openide.util.NbBundle.getMessage(EmployeeEditorTopComponent.class, "EmployeeEditorTopComponent.nicTextField.text_1")); // NOI18N
        nicTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nicTextFieldActionPerformed(evt);
            }
        });

        firstNameTextField.setText(org.openide.util.NbBundle.getMessage(EmployeeEditorTopComponent.class, "EmployeeEditorTopComponent.firstNameTextField.text_1")); // NOI18N
        firstNameTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                firstNameTextFieldActionPerformed(evt);
            }
        });

        lastNameTextField.setText(org.openide.util.NbBundle.getMessage(EmployeeEditorTopComponent.class, "EmployeeEditorTopComponent.lastNameTextField.text_1")); // NOI18N
        lastNameTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                lastNameTextFieldActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(EmployeeEditorTopComponent.class, "EmployeeEditorTopComponent.jLabel4.text_1")); // NOI18N

        codeTextField.setEditable(false);
        codeTextField.setText(org.openide.util.NbBundle.getMessage(EmployeeEditorTopComponent.class, "EmployeeEditorTopComponent.codeTextField.text_1")); // NOI18N
        codeTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                codeTextFieldActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(saveButton, org.openide.util.NbBundle.getMessage(EmployeeEditorTopComponent.class, "EmployeeEditorTopComponent.saveButton.text_1")); // NOI18N
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(clearButton, org.openide.util.NbBundle.getMessage(EmployeeEditorTopComponent.class, "EmployeeEditorTopComponent.clearButton.text_1")); // NOI18N
        clearButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel2)
                    .addComponent(jLabel1)
                    .addComponent(jLabel3)
                    .addComponent(jLabel4))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(firstNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 291, Short.MAX_VALUE)
                    .addComponent(nicTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 291, Short.MAX_VALUE)
                    .addComponent(lastNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 291, Short.MAX_VALUE)
                    .addComponent(codeTextField))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(254, Short.MAX_VALUE)
                .addComponent(clearButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(saveButton)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(14, 14, 14)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(codeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(nicTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(firstNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(lastNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(saveButton)
                    .addComponent(clearButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void nicTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nicTextFieldActionPerformed
        String nic = nicTextField.getText().trim();
        if (isNIC(nic)) {
            nicTextField.setBackground(Color.WHITE);
            firstNameTextField.requestFocus();
            fillData(nic);
        } else {
            errorField(nicTextField);
        }
    }//GEN-LAST:event_nicTextFieldActionPerformed

    private void firstNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_firstNameTextFieldActionPerformed
        if (isText(firstNameTextField.getText().trim())) {
            firstNameTextField.setBackground(Color.WHITE);
            lastNameTextField.requestFocus();
        } else {
            errorField(firstNameTextField);
        }
    }//GEN-LAST:event_firstNameTextFieldActionPerformed

    private void lastNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_lastNameTextFieldActionPerformed
        if (isText(lastNameTextField.getText().trim())) {
            lastNameTextField.setBackground(Color.WHITE);
            try {
                new EmployeeSavable().handleSave();
            } catch (IOException ex) {
                Exceptions.printStackTrace(ex);
            }
        } else {
            errorField(lastNameTextField);
        }
    }//GEN-LAST:event_lastNameTextFieldActionPerformed

    private void codeTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_codeTextFieldActionPerformed
        String codeString = codeTextField.getText().trim();
        try {
            int code = Integer.parseInt(codeString);
            Employee employee = Manager.getInstance().find(Employee.class, code);
            if (employee != null) {
                nicTextField.setText(employee.getPerson().getNic());
                firstNameTextField.setText(employee.getPerson().getFirstName());
                lastNameTextField.setText(employee.getPerson().getLastName());
                nicTextField.requestFocus();
            }
        } catch (NumberFormatException numberFormatException) {
            JOptionPane.showMessageDialog(codeTextField, "Incorrect Code");
        }
    }//GEN-LAST:event_codeTextFieldActionPerformed

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        try {
            new EmployeeSavable().handleSave();
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
    }//GEN-LAST:event_saveButtonActionPerformed

    private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
        resetFields();
    }//GEN-LAST:event_clearButtonActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton clearButton;
    private javax.swing.JTextField codeTextField;
    private javax.swing.JTextField firstNameTextField;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JTextField lastNameTextField;
    private javax.swing.JTextField nicTextField;
    private javax.swing.JButton saveButton;
    // End of variables declaration//GEN-END:variables

    void writeProperties(java.util.Properties p) {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty("version", "1.0");
        // TODO store your settings
    }

    void readProperties(java.util.Properties p) {
        String version = p.getProperty("version");
        // TODO read your settings according to their version
    }
}
